﻿using SmallJob.Model;
using SmallJob.Services.Code;
using SmallJob.Services.Interfaces;
using SmallShop.Services.Code;
using SmallShop.Services.Interfaces;
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Security;
using System.Linq;
using Caching;

namespace FrontEnd.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/
        private readonly ICategoryService _CategoryService;

        private readonly IProvideService _ProvideService;
        private readonly IUserService _UserService;
        private readonly ISkillService _SkillService;
        private readonly IBannerService _BannerService;
        private readonly IFeatureService _FeatureService;
        private readonly IFollowerService _FollowerService;
        private readonly IRequestService _RequestService;
        public HomeController(ICategoryService CategoryService, IProvideService ProvideService, IUserService UserService, ISkillService SkillService, IBannerService BannerService, IFeatureService FeatureService, IFollowerService FollowerService, IRequestService RequestService)
        {
            this._CategoryService = CategoryService;
            this._ProvideService = ProvideService;
            this._UserService = UserService;
            this._SkillService = SkillService;
            this._BannerService = BannerService;
            this._FeatureService = FeatureService;
            _FollowerService = FollowerService;
            _RequestService = RequestService;
        }

        public ActionResult Index()
        {
            ViewData["services"] = null;
            if (User.Identity.IsAuthenticated)
            {
                var user = _UserService.GetByFBID(User.Identity.Name) ?? _UserService.GetByEmail(User.Identity.Name);
                ViewData["services"] = _ProvideService.GetBuyUserID(user.ID);
                ViewData["user"] = _UserService.GetByFBID(User.Identity.Name) ?? _UserService.GetByEmail(User.Identity.Name);
                var listFollow = _FollowerService.GetUserFollow(user.ID);
                var listProvidesInterested = new List<Provide>();
                foreach (var item in listFollow)
                {
                    var lp = _ProvideService.GetBuyUserID(item.UserID);
                    foreach (var i in lp)
                    {
                        i.User = _UserService.GetById(i.UserID);
                    }
                    listProvidesInterested.AddRange(lp);
                }
                ViewData["provideInterest"] = listProvidesInterested.OrderBy(p => p.CreatedDate).ToList();
            }

            //load provide btop
            var lastest = _ProvideService.GetLastestProvide(Convert.ToInt16(Resources.Resource.LastestProvide));
            foreach (var item in lastest)
            {
                item.User = _UserService.GetById(item.UserID);
            }
            ViewData["lastest"] = lastest;
            List<Banner> listBanner = null;
            if (MemCache.Get<List<Banner>>("banner") == null)
            {
                listBanner = _BannerService.GetForSlider();
                MemCache.InsertCache("banner", listBanner);
            }
            else
            {
                listBanner = MemCache.Get<List<Banner>>("banner");
            }
            ViewData["bannerimage"] = listBanner;
            //ducnt feature
            IEnumerable<Feature> listF = null;
            if (MemCache.Get<IEnumerable<Feature>>("feature") == null)
            {
                listF = _FeatureService.All();
                MemCache.InsertCache("feature", listF);
            }
            else
            {
                listF = MemCache.Get<IEnumerable<Feature>>("feature");
            }
            var listFD = new List<FeatureDisplay>();
            foreach (Feature item in listF)
            {
                var fd = new FeatureDisplay(item);
                fd.Provides = new List<Provide>();
                List<FeatureItem> listFI = null;
                if (MemCache.Get<List<FeatureItem>>("featureitem") == null)
                {
                    listFI = _FeatureService.GetFeatureItems(item.ID);
                    MemCache.InsertCache("featureitem", listFI);
                }
                else
                {
                    listFI = MemCache.Get<List<FeatureItem>>("featureitem");
                }
                foreach (var i in listFI)
                {
                    var p = _ProvideService.GetById(i.ProvideID);
                    p.User = _UserService.GetById(p.UserID);
                    if (!p.IsDeleted)
                    {
                        fd.Provides.Add(p);
                    }
                }
                listFD.Add(fd);
            }
            ViewData["feature"] = listFD;
            var requests = _RequestService.GetForHome(Convert.ToInt32(Resources.Resource.NumberRequestForHome));
            foreach (var item in requests)
            {
                item.AssignedUser = _UserService.GetById(item.AssignedUserID);
            }
            ViewData["requests"] = requests;
            return View();
        }

        [ChildActionOnly]
        public ActionResult CategoryPartialView()
        {
            List<Category> model = null;
            if (MemCache.Get<List<Category>>("category") == null)
            {
                model = _CategoryService.GetAllAvaiable();
                MemCache.InsertCache("category", model);
            }
            else
            {
                model = MemCache.Get<List<Category>>("category");
            }
            model = UserUtility.CategorysToTree(model);
            return PartialView(model);
        }

        public ActionResult Login()
        {
            string email = Request.Form["email"];
            string password = Request.Form["password"];
            if (!string.IsNullOrWhiteSpace(email))
            {
                if (!string.IsNullOrWhiteSpace(password))
                {
                    var user = _UserService.GetByEmail(email);
                    if (user != null && user.Password == UserUtility.Encrypt(password, email))
                    {
                        FormsAuthentication.SetAuthCookie(user.FbID ?? user.Email, false);
                        MemCache.InsertCache("user_" + (user.UserName ?? user.ID.ToString()), user);
                        return Json(true);
                    }
                    if (user != null)
                    {
                        email = "";
                        password = "Mật khẩu nhập sai!";
                    }
                    else
                    {
                        email = "Email nhập không đúng!";
                        password = "";
                    }
                }
                else
                {
                    email = "";
                    password = "Mật khẩu không được bỏ trống.";
                }
            }
            else
            {
                email = "Email không được bỏ trống.";
                password = "";
            }

            return Json(new { email = email, password = password });
        }

        public ActionResult LoginFB(string fbID)
        {
            var user = _UserService.GetByFBID(fbID);
            if (user != null)
            {
                FormsAuthentication.SetAuthCookie(user.FbID ?? user.Email, false);
                MemCache.InsertCache("user_" + (user.UserName ?? user.ID.ToString()), user);
            }
            return Json(user != null);
        }

        public ActionResult LogOut()
        {
            FormsAuthentication.SignOut();
            Session["user"] = null;
            return RedirectToAction("Index", "Home");
        }

        public ActionResult SignUpFB(string fbID, string fbemail, string fbname)
        {
            if (string.IsNullOrWhiteSpace(fbID))
            {
                return Json(false);
            }
            if (string.IsNullOrWhiteSpace(fbemail))
            {
                return Json(false);
            }
            if (string.IsNullOrWhiteSpace(fbname))
            {
                return Json(false);
            }
            var user = _UserService.GetByFBID(fbID);
            if (user == null)
            {
                User u = new User()
                {
                    FbID = fbID,
                    Email = fbemail,
                    ProperName = fbname,
                    IsLock = false,
                    JoinDate = DateTime.Now
                };
                //verify thangtt
                VerifyAccount va = new VerifyAccount(u.VerifyStatus, true);
                va.CreateStatusByUSer(u);
                va.SetStatusOfStep(VerifyAccount.STEP_EMAIL, true);
                va.SetStatusOfStep(VerifyAccount.STEP_FB, true);
                va.SetStatusOfStep(VerifyAccount.STEP_NAME, true);
                u.VerifyStatus = va.GetVerifyStatus();
                _UserService.Add(u);
                MemCache.InsertCache("user_" + (u.UserName ?? u.ID.ToString()), u);
                user = u;
            }
            FormsAuthentication.SetAuthCookie(user.FbID ?? user.Email, false);
            return Json(user);
        }

        public ActionResult CheckUserName()
        {
            string us = Request.QueryString["us"];
            return Json(_UserService.CheckUserNameExist(us));
        }

        public ActionResult CompleteSignup()
        {
            string storename = Request.Form["storename"];
            string propername = Request.Form["propername"];
            string city = Request.Form["city"];
            string job = Request.Form["job"];
            string phone = Request.Form["phone"];
            string skills = Request.Form["skills"];
            if (!User.Identity.IsAuthenticated)
            {
                return Json(false);
            }
            var user = _UserService.GetByFBID(User.Identity.Name) ?? _UserService.GetByEmail(User.Identity.Name);

            if (!string.IsNullOrWhiteSpace(storename))
            {
                if (storename.Length < 4)
                {
                    storename = "Nickname nên dài hơn hoặc bằng 4 ký tự.";
                    ModelState.AddModelError("storename", storename);
                }
                else
                {
                    if (!storename.Equals(user.UserName) && _UserService.CheckUserNameExist(storename))
                    {
                        storename = "Nickname đã được dùng.";
                        ModelState.AddModelError("storename", storename);
                    }
                    else
                    {
                        user.UserName = storename;
                        storename = "";
                    }
                }
            }

            if (!string.IsNullOrWhiteSpace(propername))
            {
                user.ProperName = propername;
            }
            //set to string empty after assign to user and return json as no error
            propername = "";
            user.Location = city;
            city = "";
            user.Job = job;
            job = "";
            if (!string.IsNullOrWhiteSpace(phone))
            {
                if (!UserUtility.CheckPhone(phone))
                {
                    ModelState.AddModelError("phoneerror", "Wrong format");
                    phone = "Sai định dạng,Số điện thoại sai!";
                }
                else
                {
                    user.Phone = phone;
                    phone = "";
                }
            }
            //user.Skills = skills;
            skills = "";

            if (ModelState.IsValid)
            {
                _UserService.Update(user);
                MemCache.InsertCache("user_" + (user.UserName ?? user.ID.ToString()), user);
                return Json(true);
            }
            return Json(new { storename = storename, propername = propername, city = city, job = job, phone = phone, skills = skills });
        }

        public ActionResult GenerateVerifyCode()
        {
            if (User.Identity.IsAuthenticated)
            {
                try
                {
                    string verifycode = UserUtility.GetRandomString(10);
                    var user = _UserService.GetByFBID(User.Identity.Name) ?? _UserService.GetByEmail(User.Identity.Name);
                    user.VerifyCode = verifycode;
                    _UserService.Update(user);
                    MemCache.InsertCache("user_" + (user.UserName ?? user.ID.ToString()), user);
                    string sendmail = "Mã xác thực của bạn là : " + verifycode;
                    UserUtility.ViecNhoSendMail(user.Email, "Xác thực Email", sendmail);
                    return Json(true);
                }
                catch (Exception)
                {
                    return Json(false);
                }
            }
            return Json(false);
        }

        [HttpPost]
        public ActionResult VerifyCode()
        {
            if (User.Identity.IsAuthenticated)
            {
                try
                {
                    string verifycode = Request.Form["verifycode"];
                    var user = _UserService.GetByFBID(User.Identity.Name) ?? _UserService.GetByEmail(User.Identity.Name);
                    if (verifycode.Equals(user.VerifyCode))
                    {
                        var verify = UserUtility.GetVerifyAccount(user.VerifyStatus);
                        verify.CreateStatusByUSer(user);
                        verify.SetStatusOfStep(VerifyAccount.STEP_EMAIL, true);
                        user.VerifyStatus = verify.GetVerifyStatus();
                        _UserService.Update(user);
                        MemCache.InsertCache("user_" + (user.UserName ?? user.ID.ToString()), user);
                        var percentdone = verify.GetPercentDone();
                        return Json(new { percentdone = percentdone });
                    }
                    else
                    {
                        return Json(false);
                    }
                }
                catch (Exception)
                {
                    return Json(false);
                }
            }
            return Json(false);
        }

        [HttpPost]
        public ActionResult VerifyName()
        {
            if (User.Identity.IsAuthenticated)
            {
                try
                {
                    string name = Request.Form["name"];
                    var user = _UserService.GetByFBID(User.Identity.Name) ?? _UserService.GetByEmail(User.Identity.Name);

                    var verify = UserUtility.GetVerifyAccount(user.VerifyStatus);
                    verify.CreateStatusByUSer(user);

                    user.ProperName = name;
                    verify.SetStatusOfStep(VerifyAccount.STEP_NAME, true);

                    user.VerifyStatus = verify.GetVerifyStatus();
                    _UserService.Update(user);
                    MemCache.InsertCache("user_" + (user.UserName ?? user.ID.ToString()), user);
                    var percentdone = verify.GetPercentDone();
                    return Json(new { percentdone = percentdone });
                }
                catch (Exception)
                {
                    return Json(false);
                }
            }
            return Json(false);
        }

        [HttpPost]
        public ActionResult VerifyPhone()
        {
            if (User.Identity.IsAuthenticated)
            {
                try
                {
                    string phone = Request.Form["phone"];
                    var user = _UserService.GetByFBID(User.Identity.Name) ?? _UserService.GetByEmail(User.Identity.Name);

                    RegexPhone regex = new RegexPhone();
                    if (regex.CheckPhone(phone))
                    {
                        var verify = UserUtility.GetVerifyAccount(user.VerifyStatus);
                        verify.CreateStatusByUSer(user);

                        user.Phone = phone;
                        verify.SetStatusOfStep(VerifyAccount.STEP_PHONE, true);

                        user.VerifyStatus = verify.GetVerifyStatus();
                        _UserService.Update(user);
                        MemCache.InsertCache("user_" + (user.UserName ?? user.ID.ToString()), user);
                        var percentdone = verify.GetPercentDone();
                        return Json(new { percentdone = percentdone });
                    }
                    else
                    {
                        return Json(false);
                    }
                }
                catch (Exception)
                {
                    return Json(false);
                }
            }
            return Json(false);
        }

        public ActionResult VerifyFB(string fbID, string fbemail, string fbname)
        {
            try
            {
                if (_UserService.GetByFBID(fbID) != null)
                {
                    return Json(false);
                }
                var user = _UserService.GetByFBID(User.Identity.Name) ?? _UserService.GetByEmail(User.Identity.Name);
                user.FbID = fbID;
                bool isRealEmail = false;
                VerifyAccount va = new VerifyAccount(user.VerifyStatus, true);

                va.CreateStatusByUSer(user);
                va.SetStatusOfStep(VerifyAccount.STEP_FB, true);
                if (!user.Email.Equals(fbemail))
                {
                    user.FbEmail = fbemail;
                }
                else
                {
                    isRealEmail = true;
                    va.SetStatusOfStep(VerifyAccount.STEP_EMAIL, true);
                }

                user.ProperName = fbname;
                va.SetStatusOfStep(VerifyAccount.STEP_NAME, true);

                user.VerifyStatus = va.GetVerifyStatus();

                _UserService.Update(user);
                FormsAuthentication.SignOut();
                FormsAuthentication.SetAuthCookie(user.FbID ?? user.Email, false);
                MemCache.InsertCache("user_" + (user.UserName ?? user.ID.ToString()), user);
                var percentdone = va.GetPercentDone();
                return Json(new { percentdone = percentdone, isrealemail = isRealEmail });
            }
            catch (Exception)
            {
                return Json(false);
            }
        }

        public ActionResult GetUserID(string fbID)
        {
            return Json(_UserService.GetByFBID(fbID).ID);
        }

        public ActionResult AddFBAvatar(string fbID, string url)
        {
            var u = _UserService.GetByFBID(fbID);
            u.Avatar = url;

            VerifyAccount va = new VerifyAccount(u.VerifyStatus, true);
            va.CreateStatusByUSer(u);
            va.SetStatusOfStep(VerifyAccount.STEP_AVATAR, true);

            u.VerifyStatus = va.GetVerifyStatus();

            _UserService.Update(u);
            MemCache.InsertCache("user_" + (u.UserName ?? u.ID.ToString()), u);
            return Json(true);
        }

        //public ActionResult BetaKey()
        //{
        //    String betakey = Request.Form["betakey"];
        //    if (User.Identity.IsAuthenticated)
        //    {
        //        var u = _UserService.GetByFBID(User.Identity.Name) ?? _UserService.GetByEmail(User.Identity.Name);
        //        if (betakey == "betaviecnho")
        //        {
        //            u.BetaTester = true;
        //            _UserService.Update(u);
        //            ZCache.InsertCache("user_" + (u.UserName ?? u.ID.ToString()), u, ZCacheTime.OneDay);
        //            return Json(true);
        //        }
        //    }
        //    return Json(false);
        //}
        public ActionResult Notify()
        {
            return View();
        }
        public ActionResult DeleteCache(string key)
        {
            MemCache.RemoveCache(key);
            ViewData["rc"] = "Đã xóa";
            return View("CacheRemove");
        }
        public ActionResult CacheRemove()
        {
            return View();
        }
    }
}